{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "std::cout are redirected to python::stdout\n",
      "std::cerr are redirected to python::stderr\n",
      "2022-07-23 15:03:55.353 [HKU-I] - Using SQLITE3 BaseInfoDriver (BaseInfoDriver.cpp:58)\n",
      "2022-07-23 15:03:55.354 [HKU-I] - Loading market information... (StockManager.cpp:497)\n",
      "2022-07-23 15:03:55.354 [HKU-I] - Loading stock type information... (StockManager.cpp:510)\n",
      "2022-07-23 15:03:55.354 [HKU-I] - Loading stock information... (StockManager.cpp:424)\n",
      "2022-07-23 15:03:55.400 [HKU-I] - Loading stock weight... (StockManager.cpp:527)\n",
      "2022-07-23 15:03:55.732 [HKU-I] - Loading KData... (StockManager.cpp:139)\n",
      "2022-07-23 15:03:55.735 [HKU-I] - Preloading all day kdata to buffer! (StockManager.cpp:162)\n",
      "2022-07-23 15:03:55.735 [HKU-I] - Preloading all week kdata to buffer! (StockManager.cpp:165)\n",
      "2022-07-23 15:03:55.735 [HKU-I] - Preloading all month kdata to buffer! (StockManager.cpp:168)\n",
      "2022-07-23 15:03:55.735 [HKU-W] - Current hdf5 library is not thread-safe! (H5KDataDriver.h:36)\n",
      "2022-07-23 15:04:11.210 [HKU-I] - 15.48s Loaded Data. (StockManager.cpp:150)\n",
      "Wall time: 16.3 s\n"
     ]
    }
   ],
   "source": [
    "%matplotlib inline\n",
    "%time from hikyuu.interactive import *\n",
    "use_draw_engine('matplotlib')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 一、策略分析\n",
    "\n",
    "## 原始描述\n",
    "\n",
    "建仓条件：expma周线exp1跟exp2金叉向上使用使用 B=50% 的资金买入股票，建仓成功后，卖出条件才能起作用\n",
    "\n",
    "卖出条件S1：expma日线exp1和exp2死叉向下时卖出持仓股 S=50%\n",
    "\n",
    "买入条件B1：expma日线exp1和exp2金叉向上时买入股票数为S（卖出条件S1卖出股数）\n",
    "\n",
    "S1和B1就这样循环\n",
    "\n",
    "清仓条件为：expma周线exp1和exp2死叉时\n",
    "\n",
    "\n",
    "## 策略分析\n",
    "\n",
    "市场环境：无\n",
    "\n",
    "系统有效性：周线EMA1（快线）和EMA2（慢线）金叉向上直到两者死叉，系统有效时建立初始仓位\n",
    "\n",
    "信号指示器：\n",
    "- 买入：日线EMA1（快线）和EMA2（慢线）金叉向上\n",
    "- 卖出：日线EMA1（快线）和EMA2（慢线）死叉向下\n",
    "\n",
    "止损/止盈：无\n",
    "\n",
    "资金管理：\n",
    "- 初次建仓：使用50%的资金\n",
    "- 买入：初次建仓时持股数的50%\n",
    "- 卖出：初次建仓时持股数的50%\n",
    "\n",
    "盈利目标：无\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 二、实现系统部件\n",
    "\n",
    "## 自定义系统有效性策略"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "def getNextWeekDateList(week):\n",
    "    from datetime import timedelta\n",
    "    py_week = week.datetime()\n",
    "    next_week_start = py_week + timedelta(days = 7 - py_week.weekday())\n",
    "    next_week_end = next_week_start + timedelta(days=5)\n",
    "    return get_date_range(Datetime(next_week_start), Datetime(next_week_end))\n",
    "#ds = getNextWeekDateList(Datetime(201801010000))\n",
    "#for d in ds:\n",
    "#    print(d)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "def DEMO_CN(self):\n",
    "    \"\"\" DIF > DEA 时，系统有效\n",
    "    参数：\n",
    "    fast_n：周线dif窗口\n",
    "    slow_n: 周线dea窗口\n",
    "    \"\"\"\n",
    "    k = self.to\n",
    "    if (len(k) <= 10):\n",
    "        return\n",
    "    \n",
    "    #-----------------------------\n",
    "    # 周线        \n",
    "    #-----------------------------\n",
    "    week_q = Query(k[0].datetime, k[-1].datetime, ktype=Query.WEEK)\n",
    "    week_k = k.get_stock().get_kdata(week_q)\n",
    "    \n",
    "    n1 = self.get_param(\"week_macd_n1\")\n",
    "    n2 = self.get_param(\"week_macd_n2\")\n",
    "    n3 = self.get_param(\"week_macd_n3\")\n",
    "    m = MACD(CLOSE(week_k), n1, n2, n3)\n",
    "    fast = m.get_result(0)\n",
    "    slow = m.get_result(1)\n",
    "\n",
    "    x = fast > slow\n",
    "    for i in range(x.discard, len(x)-1):\n",
    "        if (x[i] >= 1.0):\n",
    "            #需要被扩展到日线（必须是后一周）\n",
    "            date_list = getNextWeekDateList(week_k[i].datetime)\n",
    "            for d in date_list:\n",
    "                self._add_valid(d)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 自定义信号指示器"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "#这个例子不需要，已经有内建的SG_Cross函数可直接使用"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 自定义资金管理策略"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "class DEMO_MM(MoneyManagerBase):\n",
    "    \"\"\"\n",
    "    初次建仓：使用50%的资金\n",
    "    买入：初次建仓时持股数的50%\n",
    "    卖出：初次建仓时持股数的50%\n",
    "    \"\"\"\n",
    "    def __init__(self):\n",
    "        super(DEMO_MM, self).__init__(\"MACD_MM\")\n",
    "        self.set_param(\"init_position\", 0.5) #自定义初始仓位参数，占用资金百分比\n",
    "        self.next_buy_num = 0\n",
    "        \n",
    "    def _reset(self):\n",
    "        self.next_buy_num = 0\n",
    "        #pass\n",
    "        \n",
    "    def _clone(self):\n",
    "        mm = DEMO_MM()\n",
    "        mm.next_buy_num = self.next_buy_num\n",
    "        #return DEMO_MM()\n",
    "    \n",
    "    def _get_buy_num(self, datetime, stk, price, risk, part_from):\n",
    "        tm = self.tm\n",
    "        cash = tm.current_cash\n",
    "        \n",
    "        #如果信号来源于系统有效条件，建立初始仓位\n",
    "        if part_from == System.Part.CONDITION:\n",
    "            #return int((cash * 0.5 // price // stk.atom) * stk.atom)  #MoneyManagerBase其实已经保证了买入是最小交易数的整数\n",
    "            self.next_buy_num = 0 #清理掉上一周期建仓期间滚动买卖的股票数\n",
    "            return int(cash * self.get_param(\"init_position\") // price)\n",
    "        \n",
    "        #非初次建仓，买入同等数量\n",
    "        return self.next_buy_num\n",
    "    \n",
    "    def _getSellNumber(self, datetime, stk, price, risk, part_from):\n",
    "        tm = self.tm\n",
    "        position = tm.get_position(datetime, stk)\n",
    "        current_num = int(position.number * 0.5)\n",
    "        \n",
    "        #记录第一次卖出时的股票数，以便下次以同等数量买入\n",
    "        if self.next_buy_num == 0:\n",
    "            self.next_buy_num = current_num \n",
    "            \n",
    "        return current_num #返回类型必须是整数"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 三、构建并运行系统\n",
    "\n",
    "## 修改设定公共参数\n",
    "\n",
    "每个系统部件以及TradeManager都有自己的公共参数会影响系统运行，具体可以查看帮助及试验。\n",
    "\n",
    "比如：这个例子当前使用系统有效条件进行初始建仓，那么必须设置系统公共参数cn_open_position为True。否则，没有建立初始仓位的话，后续没有卖出，不会有任何交易。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "#System参数\n",
    "#delay=True #(bool) : 是否延迟到下一个bar开盘时进行交易\n",
    "#delay_use_current_price=True #(bool) : 延迟操作的情况下，是使用当前交易时bar的价格计算新的止损价/止赢价/目标价还是使用上次计算的结果\n",
    "#max_delay_count=3 #(int) : 连续延迟交易请求的限制次数\n",
    "#tp_monotonic=True #(bool) : 止赢单调递增\n",
    "#tp_delay_n=3 #(int) : 止盈延迟开始的天数，即止盈策略判断从实际交易几天后开始生效\n",
    "#ignore_sell_sg=False #(bool) : 忽略卖出信号，只使用止损/止赢等其他方式卖出\n",
    "#ev_open_position=False #(bool): 是否使用市场环境判定进行初始建仓\n",
    "\n",
    "cn_open_position=True #(bool): 是否使用系统有效性条件进行初始建仓\n",
    "\n",
    "#MoneyManager公共参数\n",
    "#auto-checkin=False #(bool) : 当账户现金不足以买入资金管理策略指示的买入数量时，自动向账户中补充存入（checkin）足够的现金。\n",
    "#max-stock=20000 #(int) : 最大持有的证券种类数量（即持有几只股票，而非各个股票的持仓数）\n",
    "#disable_ev_force_clean_position=False #(bool) : 禁用市场环境失效时强制清仓\n",
    "#disable_cn_force_clean_position=False #(bool) : 禁用系统有效条件失效时强制清仓\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 设定私有参数及待测试标的"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "#账户参数\n",
    "init_cash = 500000 #账户初始资金\n",
    "init_date = '1990-1-1' #账户建立日期\n",
    "\n",
    "#信号指示器参数\n",
    "week_n1 = 12\n",
    "week_n2 = 26\n",
    "week_n3 = 9\n",
    "\n",
    "#选定标的，及测试区间\n",
    "stk = sm['sz000002']\n",
    "\n",
    "#如果是同一级别K线，可以使用索引号，使用了不同级别的K线数据，建议还是使用日期作为参数\n",
    "#另外，数据量太大的话，matplotlib绘图会比较慢\n",
    "start_date = Datetime('2016-01-01')  \n",
    "end_date = Datetime()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "## 构建系统实例"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "#创建模拟交易账户进行回测，初始资金30万\n",
    "my_tm = crtTM(date=Datetime(init_date), init_cash = init_cash)\n",
    "\n",
    "#创建系统实例\n",
    "my_sys = SYS_Simple()\n",
    "\n",
    "my_sys.set_param(\"cn_open_position\", cn_open_position)\n",
    "\n",
    "my_sys.tm = my_tm\n",
    "my_sys.cn = crtCN(DEMO_CN, \n",
    "              {'week_macd_n1': week_n1, 'week_macd_n2': week_n2, 'week_macd_n3': week_n3}, \n",
    "                'DEMO_CN')  \n",
    "my_sys.sg = SG_Cross(EMA(n=week_n1), EMA(n=week_n2))\n",
    "my_sys.mm = DEMO_MM()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 运行系统"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "q = Query(start_date, end_date, ktype=Query.DAY)\n",
    "my_sys.run(stk, q)\n",
    "\n",
    "#将交易记录及持仓情况，保存在临时目录，可用Excel查看\n",
    "#临时目录一般设置在数据所在目录下的 tmp 子目录\n",
    "#如果打开了excel记录，再次运行系统前，记得先关闭excel文件，否则新的结果没法保存\n",
    "my_tm.tocsv(sm.tmpdir())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 四、查看资金曲线及绩效统计"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 720x576 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "#绘制资金收益曲线\n",
    "x = my_tm.get_profit_curve(stk.get_datetime_list(q), Query.DAY)\n",
    "#x = my_tm.getFundsCurve(stk.getDatetimeList(q), KQuery.DAY) #资金净值曲线\n",
    "PRICELIST(x).plot()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "帐户初始金额: 500000.00\n",
      "累计投入本金: 500000.00\n",
      "累计投入资产: 0.00\n",
      "累计借入现金: 0.00\n",
      "累计借入资产: 0.00\n",
      "累计红利: 35986.00\n",
      "现金余额: 597058.00\n",
      "未平仓头寸净值: 0.00\n",
      "当前总资产: 597058.00\n",
      "已平仓交易总成本: 0.00\n",
      "已平仓净利润总额: 97058.00\n",
      "单笔交易最大占用现金比例%: 49.96\n",
      "交易平均占用现金比例%: 49.81\n",
      "已平仓帐户收益率%: 19.41\n",
      "帐户年复合收益率%: 2.99\n",
      "帐户平均年收益率%: 3.23\n",
      "赢利交易赢利总额: 207404.00\n",
      "亏损交易亏损总额: -110346.00\n",
      "已平仓交易总数: 9.00\n",
      "赢利交易数: 5.00\n",
      "亏损交易数: 4.00\n",
      "赢利交易比例%: 55.56\n",
      "赢利期望值: 10784.22\n",
      "赢利交易平均赢利: 41480.80\n",
      "亏损交易平均亏损: -27586.50\n",
      "平均赢利/平均亏损比例: 1.50\n",
      "净赢利/亏损比例: 1.88\n",
      "最大单笔赢利: 140712.00\n",
      "最大单笔亏损: -55022.00\n",
      "赢利交易平均持仓时间: 34.80\n",
      "赢利交易最大持仓时间: 71.00\n",
      "亏损交易平均持仓时间: 55.00\n",
      "亏损交易最大持仓时间: 94.00\n",
      "空仓总时间: 1802.00\n",
      "空仓时间/总时间%: 82.00\n",
      "平均空仓时间: 200.00\n",
      "最长空仓时间: 431.00\n",
      "最大连续赢利笔数: 3.00\n",
      "最大连续亏损笔数: 3.00\n",
      "最大连续赢利金额: 142428.00\n",
      "最大连续亏损金额: -69282.00\n",
      "R乘数期望值: 0.05\n",
      "交易机会频率/年: 1.50\n",
      "年度期望R乘数: 0.07\n",
      "赢利交易平均R乘数: 0.16\n",
      "亏损交易平均R乘数: -0.09\n",
      "最大单笔赢利R乘数: 0.57\n",
      "最大单笔亏损R乘数: -0.17\n",
      "最大连续赢利R乘数: 0.19\n",
      "最大连续亏损R乘数: -0.11\n",
      "\n"
     ]
    }
   ],
   "source": [
    "#回测统计\n",
    "per = Performance()\n",
    "print(per.report(my_tm, Datetime.now()))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 五、或许想看下图形"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "#自己写吧"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "# 六、或许想看看所有股票的情况"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2022-07-23 15:04:11.887 [HKU-I] - Over stock.maxTradeNumber(1000000)! (MoneyManagerBase.cpp:116)\n",
      "2022-07-23 15:04:11.887 [HKU-I] - Over stock.maxTradeNumber(1000000)! (MoneyManagerBase.cpp:116)\n",
      "2022-07-23 15:04:12.076 [HKU-I] - Over stock.maxTradeNumber(1000000)! (MoneyManagerBase.cpp:116)\n",
      "2022-07-23 15:04:12.076 [HKU-I] - Over stock.maxTradeNumber(1000000)! (MoneyManagerBase.cpp:116)\n",
      "2022-07-23 15:04:13.372 [HKU-I] - Over stock.maxTradeNumber(1000000)! (MoneyManagerBase.cpp:116)\n",
      "2022-07-23 15:04:13.372 [HKU-I] - Over stock.maxTradeNumber(1000000)! (MoneyManagerBase.cpp:116)\n",
      "2022-07-23 15:04:13.895 [HKU-I] - Over stock.maxTradeNumber(1000000)! (MoneyManagerBase.cpp:116)\n",
      "2022-07-23 15:04:13.896 [HKU-I] - Over stock.maxTradeNumber(1000000)! (MoneyManagerBase.cpp:116)\n",
      "2022-07-23 15:04:14.752 [HKU-I] - Over stock.maxTradeNumber(1000000)! (MoneyManagerBase.cpp:116)\n",
      "2022-07-23 15:04:14.752 [HKU-I] - Over stock.maxTradeNumber(1000000)! (MoneyManagerBase.cpp:116)\n",
      "2022-07-23 15:04:18.178 [HKU-I] - Over stock.maxTradeNumber(1000000)! (MoneyManagerBase.cpp:116)\n",
      "2022-07-23 15:04:18.178 [HKU-I] - Over stock.maxTradeNumber(1000000)! (MoneyManagerBase.cpp:116)\n",
      "Wall time: 9.09 s\n"
     ]
    }
   ],
   "source": [
    "import pandas as pd\n",
    "def calTotal(blk, q):\n",
    "    per = Performance()\n",
    "    s_name = []\n",
    "    s_code = []\n",
    "    x = []\n",
    "    for stk in blk:\n",
    "        my_sys.run(stk, q)\n",
    "        per.statistics(my_tm, Datetime.now())\n",
    "        s_name.append(stk.name)\n",
    "        s_code.append(stk.market_code)\n",
    "        x.append(per[\"当前总资产\"])\n",
    "    return pd.DataFrame({'代码': s_code, '股票': s_name, '当前总资产': x})\n",
    "\n",
    "%time data = calTotal(blocka, q)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>代码</th>\n",
       "      <th>股票</th>\n",
       "      <th>当前总资产</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>SH600770</td>\n",
       "      <td>综艺股份</td>\n",
       "      <td>591947.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>SZ000532</td>\n",
       "      <td>华金资本</td>\n",
       "      <td>581418.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>SZ300238</td>\n",
       "      <td>冠昊生物</td>\n",
       "      <td>689027.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>SH601777</td>\n",
       "      <td>力帆科技</td>\n",
       "      <td>801564.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>SH600781</td>\n",
       "      <td>*ST辅仁</td>\n",
       "      <td>492755.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>SH600671</td>\n",
       "      <td>ST目药</td>\n",
       "      <td>391659.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>SZ002888</td>\n",
       "      <td>惠威科技</td>\n",
       "      <td>733720.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>SH603599</td>\n",
       "      <td>广信股份</td>\n",
       "      <td>536307.9</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>SH600086</td>\n",
       "      <td>*ST金钰</td>\n",
       "      <td>621961.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>SH600363</td>\n",
       "      <td>联创光电</td>\n",
       "      <td>633882.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         代码     股票     当前总资产\n",
       "0  SH600770   综艺股份  591947.0\n",
       "1  SZ000532   华金资本  581418.0\n",
       "2  SZ300238   冠昊生物  689027.0\n",
       "3  SH601777   力帆科技  801564.0\n",
       "4  SH600781  *ST辅仁  492755.0\n",
       "5  SH600671   ST目药  391659.0\n",
       "6  SZ002888   惠威科技  733720.0\n",
       "7  SH603599   广信股份  536307.9\n",
       "8  SH600086  *ST金钰  621961.0\n",
       "9  SH600363   联创光电  633882.0"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#保存到CSV文件\n",
    "#data.to_csv(sm.tmpdir() + '/统计.csv')\n",
    "data[:10]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
